package com.demo.common.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.demo.common.exception.RRException;

import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 序列号工具
 *
 * @author Zsx
 * @date 2019年7月9日
 * @since 1.0
 */
public class SerialNumUtils {

    /**
     * 获取下一编码，简洁模式：无前缀，当前日期yyyyMMdd + 默认6位流水
     */
    public static String nextSimpleDateSerial(String nowMaxCode) {
        return next(null, 6, nowMaxCode, new Date());
    }

    /**
     * 根据最大的完整业务编码获取下一编码
     *
     * @param prefix     前缀
     * @param codeLength 流水号长度
     * @param nowDate    当前日期
     * @param nowMaxCode 当前最大的完整业务编码
     */
    public static String next(String prefix, int codeLength, String nowMaxCode, Date nowDate) {
        String newStrNum = null;
        //初始配置
        //初始值
        int nowNum = 0;
        AtomicInteger atomicNum = new AtomicInteger();
        atomicNum.set(nowNum);
        //初始日期
        String nowDateStr = "";
        try {
            //传入参数处理
            //前缀处理
            if (prefix == null) {
                prefix = "";
            }
            //日期处理
            if (nowDate != null) {
                nowDateStr = DateUtil.format(nowDate, "yyyyMMdd");
            }
            //当前最大编号处理
            if (StrUtil.isNotBlank(nowMaxCode)) {
                //去掉前缀
                String codeStr = nowMaxCode.replace(prefix, "");
                if (StrUtil.isNotBlank(codeStr)) {
                    if (StrUtil.isNotBlank(nowDateStr)) {
                        //编码中的日期
                        String codeDateStr = codeStr.substring(0, 8);
                        //编码
                        codeStr = codeStr.substring(8);
                        if (nowDateStr.equals(codeDateStr)) {
                            nowNum = Integer.parseInt(codeStr);
                        }
                    } else {
                        nowNum = Integer.parseInt(codeStr);
                    }
                }
            }

            atomicNum.set(nowNum);
            int newNum = atomicNum.incrementAndGet();
            newStrNum = prefix + nowDateStr + String.format("%0" + codeLength + "d", newNum);
        } catch (Exception e) {
            throw new RRException(StrUtil.format("生成下一流水号出错：当前传入完整流水号为【{}】，传入前缀为【{}】，传入日期为【{}】", nowMaxCode, prefix, nowDateStr), e);
        }
        return newStrNum;
    }
}
